#ifdef MEMMAN_EXPORTS
#define MEMMAN_API __declspec(dllexport)
#else
#define MEMMAN_API __declspec(dllimport)
#endif

#define retbool return 0xFF & (int)

#include <vector>
using namespace std;


class CMemMan {
public:
	CMemMan();
	~CMemMan();

	static enum Collections
	{
		Type,
		Service,
		Time,
		Message
	};

	void PushLine(char* data);
	unsigned PushBulk(char* data, unsigned length);
	unsigned GetEventsCountForThread(unsigned threadIdx, bool useFilter);
	unsigned GetThreadIndex(short tid);
	unsigned GetThreadsCount();
	unsigned GetServicesCount();
	short GetTidForIndex(unsigned threadIdx);
	char* GetEventData(unsigned threadIdx, unsigned eventIdx, Collections colId, bool useFilter);
	char* GetServiceById(unsigned idx);
	void ExpandEventMessage(char* msg, char* buffer);
	void ExpandEventTime(int time, char* buffer);
	void AddFilter(char* data, Collections colId);
	void ClearFilter();
	void ApplyFilter(unsigned threadIdx);
	unsigned GetFilteredThreadIdx();

private:
	void Clear();
	void DeleteCharPtrCol(vector<char*>** vect);
	void Init();
	char GetCharPtrColItemIndex(char* item, size_t sz, vector<char*>* vect);
	short GetCharPtrColItemIndexEx(char* item, size_t sz, vector<char*>* vect);
	unsigned CharPtrColContainsItem(char* item, size_t sz, vector<char*>* vect);
	unsigned CharColContainsItem(char item, vector<char>* vect);
	char GetTypeFast(char* ptr);
	short Hex2Short(char** hex);
	int GetTimeFast(char* ptr);
	char* PackLine(char* src);
	inline vector<char*>* GetDictionary(char one, char two);

	struct line
	{
		char* Msg;		//packed content put into _msgHeap; lexems are in dictionary[][] collections array
		char Srv;		//Index in srvs collection
		char Type;		//See GetTypeFast() for enum values
		int  Time;		//Packed:
						//h	0-23	5 bit - byte #1
						//m	0-59	7 bit - Byte #2
						//s	0-59	6 bit - byte #3
						//ms0-999	10 bit - bits 7-8 of byte #3 + byte#4
	};

	vector<short> *threads;	
	vector<char*> *srvs;
	vector<vector<line>*> *globalCollection;

	vector<char*> *dictionary[256][256];

	vector<char> *_typeFilter;
	vector<char*> *_serviceFilter;
	vector<unsigned> *_threadFilter;

	HANDLE _heap, _msgHeap;
	unsigned _filteredThreadIdx;
};
